package com.study.crypto.utils;

import java.nio.ByteBuffer;

/**
 * @author Songjin
 * @since 2021/1/12 23:48
 */
public final class ByteUtility {
	
	private ByteUtility() {
	}
	
	/**
	 * 将int转换为字节数组
	 * @param inData 整数
	 * @return 字节数组
	 */
	public static byte[] intToByte(int inData) {
		ByteBuffer byteBuf = ByteBuffer.allocate(4);
		byteBuf.putInt(inData);
		return byteBuf.array();
	}
	
	/**
	 * 将字节数组转换为int
	 * @param inData 字节数组
	 * @return 整数
	 */
	public static int byteToInt(byte[] inData) {
		ByteBuffer byteBuf = ByteBuffer.allocate(4);
		byteBuf.put(inData);
		return byteBuf.getInt(0);
	}
	
	public static byte[] addBytes(byte[] array, byte[] value) {
		if (null != array) {
			byte[] newarray = new byte[array.length + value.length];
			System.arraycopy(array, 0, newarray, 0, array.length);
			System.arraycopy(value, 0, newarray, array.length, value.length);
			array = newarray;
		} else {
			array = value;
		}
		
		return array;
	}
	
	public static byte[] addBytes(byte[] array, byte value) {
		if (null != array) {
			byte[] newarray = new byte[array.length + 1];
			System.arraycopy(array, 0, newarray, 0, array.length);
			newarray[newarray.length - 1] = value;
			array = newarray;
		} else {
			array = new byte[]{value};
		}
		
		return array;
	}
	
	public static byte[] addBytes(byte[] array, int value) {
		if (null != array) {
			byte[] newarray = new byte[array.length + 3];
			System.arraycopy(array, 0, newarray, 0, array.length);
			newarray[newarray.length - 3] = (byte) (value >> 16 & 255);
			newarray[newarray.length - 2] = (byte) (value >> 8 & 255);
			newarray[newarray.length - 1] = (byte) (value & 255);
			array = newarray;
		} else {
			array = new byte[]{(byte) (value >> 16 & 255), (byte) (value >> 8 & 255), (byte) (value & 255)};
		}
		
		return array;
	}
	
	public static byte[] addBytes(byte[] array, long value) {
		if (null != array) {
			byte[] newarray = new byte[array.length + 4];
			System.arraycopy(array, 0, newarray, 0, array.length);
			newarray[newarray.length - 4] = (byte) ((int) (value >> 24 & 255L));
			newarray[newarray.length - 3] = (byte) ((int) (value >> 16 & 255L));
			newarray[newarray.length - 2] = (byte) ((int) (value >> 8 & 255L));
			newarray[newarray.length - 1] = (byte) ((int) (value & 255L));
			array = newarray;
		} else {
			array = new byte[]{(byte) ((int) (value >> 24 & 255L)), (byte) ((int) (value >> 16 & 255L)), (byte) ((int) (value >> 8 & 255L)), (byte) ((int) (value & 255L))};
		}
		
		return array;
	}
	
	public static byte[] addBytes(byte[] array, String value) {
		if (null != value) {
			if (null != array) {
				byte[] newarray = new byte[array.length + value.length()];
				System.arraycopy(array, 0, newarray, 0, array.length);
				System.arraycopy(value.getBytes(), 0, newarray, array.length, value.length());
				array = newarray;
			} else {
				array = value.getBytes();
			}
		}
		
		return array;
	}
	
	public static byte[] addBytes(byte[] array, short value) {
		if (null != array) {
			byte[] newarray = new byte[array.length + 2];
			System.arraycopy(array, 0, newarray, 0, array.length);
			newarray[newarray.length - 2] = (byte) (value >> 8 & 255);
			newarray[newarray.length - 1] = (byte) (value & 255);
			array = newarray;
		} else {
			array = new byte[]{(byte) (value >> 8 & 255), (byte) (value & 255)};
		}
		
		return array;
	}
	
	public static double byteArrayToDouble(byte[] high, byte[] low) {
		double temp = 0.0D;
		temp += (double) (((long) high[0] & 255L) << 56);
		temp += (double) (((long) high[1] & 255L) << 48);
		temp += (double) (((long) high[2] & 255L) << 40);
		temp += (double) (((long) high[3] & 255L) << 32);
		temp += (double) (((long) low[0] & 255L) << 24);
		temp += (double) (((long) low[1] & 255L) << 16);
		temp += (double) (((long) low[2] & 255L) << 8);
		temp += (double) ((long) low[3] & 255L);
		return temp;
	}
	
	public static double byteArrayToDouble(byte[] value) {
		byte[] high = new byte[4];
		byte[] low = new byte[4];
		high[0] = value[0];
		high[1] = value[1];
		high[2] = value[2];
		high[3] = value[3];
		low[0] = value[4];
		low[1] = value[5];
		low[2] = value[6];
		low[3] = value[7];
		return byteArrayToDouble(high, low);
	}
	
	public static float byteArrayToFloat(byte[] value) {
		float temp = 0.0F;
		temp += (float) ((value[0] & 255) << 24);
		temp += (float) ((value[1] & 255) << 16);
		temp += (float) ((value[2] & 255) << 8);
		temp += (float) (value[3] & 255);
		return temp;
	}
	
	public static int byteArrayToInt(byte[] value) {
		int temp = 0;
		temp += (value[0] & 255) << 24;
		temp += (value[1] & 255) << 16;
		temp += (value[2] & 255) << 8;
		temp += value[3] & 255;
		return temp;
	}
	
	public static long byteArrayToLong(byte[] value) {
		byte[] high = new byte[4];
		byte[] low = new byte[4];
		high[0] = value[0];
		high[1] = value[1];
		high[2] = value[2];
		high[3] = value[3];
		low[0] = value[4];
		low[1] = value[5];
		low[2] = value[6];
		low[3] = value[7];
		return byteArrayToLong(high, low);
	}
	
	public static byte[] longToByte(long number) {
		byte[] bytes = new byte[8];
		bytes[0] = (byte) (number & 0xff);
		bytes[1] = (byte) ((number >> 8) & 0xff);
		bytes[2] = (byte) ((number >> 16) & 0xff);
		bytes[3] = (byte) ((number >> 24) & 0xff);
		bytes[4] = (byte) ((number >> 32) & 0xff);
		bytes[5] = (byte) ((number >> 40) & 0xff);
		bytes[6] = (byte) ((number >> 48) & 0xff);
		bytes[7] = (byte) ((number >> 56) & 0xff);
		return bytes;
	}
	
	public static long byteArrayToLong(byte[] high, byte[] low) {
		long temp = 0L;
		temp += ((long) high[0] & 255L) << 56;
		temp += ((long) high[1] & 255L) << 48;
		temp += ((long) high[2] & 255L) << 40;
		temp += ((long) high[3] & 255L) << 32;
		temp += ((long) low[0] & 255L) << 24;
		temp += ((long) low[1] & 255L) << 16;
		temp += ((long) low[2] & 255L) << 8;
		temp += (long) low[3] & 255L;
		return temp;
	}
	
	public static long asLong(byte[] value) {
		ByteBuffer buffer2 = ByteBuffer.allocate(Long.BYTES);
		buffer2.put(value);
		buffer2.flip();
		return buffer2.getLong();
	}
	
	public static byte[] asBytes(long value) {
		ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
		buffer.putLong(value);
		return buffer.array();
	}
	
	public static short byteArrayToShort(byte[] value) {
		short temp = 0;
		temp = (short) (temp + ((value[0] & 255) << 8));
		temp = (short) (temp + (value[1] & 255));
		return temp;
	}
	
	public static String byteToHexString(byte value) {
		String temp = null;
		switch ((value & 240) >> 4) {
			case 0:
				temp = "0";
				break;
			case 1:
				temp = "1";
				break;
			case 2:
				temp = "2";
				break;
			case 3:
				temp = "3";
				break;
			case 4:
				temp = "4";
				break;
			case 5:
				temp = "5";
				break;
			case 6:
				temp = "6";
				break;
			case 7:
				temp = "7";
				break;
			case 8:
				temp = "8";
				break;
			case 9:
				temp = "9";
				break;
			case 10:
				temp = "A";
				break;
			case 11:
				temp = "B";
				break;
			case 12:
				temp = "C";
				break;
			case 13:
				temp = "D";
				break;
			case 14:
				temp = "E";
				break;
			case 15:
				temp = "F";
		}
		
		switch (value & 15) {
			case 0:
				temp = temp + "0";
				break;
			case 1:
				temp = temp + "1";
				break;
			case 2:
				temp = temp + "2";
				break;
			case 3:
				temp = temp + "3";
				break;
			case 4:
				temp = temp + "4";
				break;
			case 5:
				temp = temp + "5";
				break;
			case 6:
				temp = temp + "6";
				break;
			case 7:
				temp = temp + "7";
				break;
			case 8:
				temp = temp + "8";
				break;
			case 9:
				temp = temp + "9";
				break;
			case 10:
				temp = temp + "A";
				break;
			case 11:
				temp = temp + "B";
				break;
			case 12:
				temp = temp + "C";
				break;
			case 13:
				temp = temp + "D";
				break;
			case 14:
				temp = temp + "E";
				break;
			case 15:
				temp = temp + "F";
		}
		
		return temp;
	}
}
